package com.mxpio.erp.plm.service.impl;

import cn.hutool.core.util.StrUtil;
import com.mxpio.erp.common.plm.entity.ProjectProblemSort;
import com.mxpio.erp.common.plm.entity.ProjectTaskDeliverableTemplate;
import com.mxpio.erp.common.plm.entity.ProjectTaskTemplate;
import com.mxpio.erp.common.plm.service.ProjectProblemSortService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 *  问题分类树状图
 *  @author qb
 *  @since 2024-2-26
 */
@Service
public class ProjectProblemSortServiceImpl extends BaseServiceImpl<ProjectProblemSort> implements ProjectProblemSortService {
    /**
     * 对信息进行更新
     * @param problemSort
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> updateProblem(ProjectProblemSort problemSort) {
        if (problemSort.getProblemCode().equals(problemSort.getParentCode())){
            return Result.error("父级编码不能等于自身编码");
        }
        //对父类子类，进行死循环检验
        ProjectProblemSort byId = this.getById(ProjectProblemSort.class, problemSort.getProblemCode());
        String problemCode = byId.getProblemCode();
        List<ProjectProblemSort> childrenTasks = this.getChildren(byId.getProType(), problemCode);
        List<String> problemCodes = childrenTasks.stream().map(ProjectProblemSort::getProblemCode).collect(Collectors.toList());
//        problemCodes.add(problemCode);
        for (String problem : problemCodes){
            if (problem.equals(problemSort.getParentCode())){
                return Result.error("子级不能为父级的父级");
            }
        }


        if (problemSort.getParentCode()==null){//判断父级编码是否存在
            List<ProjectProblemSort> children = problemSort.getChildren();
            for (ProjectProblemSort child : children)
                child.setProType(problemSort.getProType());//对子级的问题类型进行更改
            this.update(children);
        }
        this.update(problemSort);
        return Result.OK("更新成功");


    }


    /**
     * 获取所有子级
     */
    public List<ProjectProblemSort> getChildren(String proType, String parentCode) {
        // 获取当前项目类型下的所有问题分类
        List<ProjectProblemSort> allSort = JpaUtil.linq(ProjectProblemSort.class).equal("proType", proType).list();

        // 初始化用于收集所有子任务的平铺列表
        List<ProjectProblemSort> flatChildrenList = new ArrayList<>();

        // 填充子任务列表
        findAllChildren(allSort, parentCode, flatChildrenList);

        return flatChildrenList;
    }

    /**
     * 递归辅助方法，用于收集所有子级到平铺列表中
     */

    private void findAllChildren(List<ProjectProblemSort> allSort, String parentCode, List<ProjectProblemSort> flatChildrenList) {
        // 从所有任务中过滤出当前父任务代码下的直接子任务
        List<ProjectProblemSort> children = allSort.stream().filter(sort ->
                (StrUtil.isEmpty(parentCode) ? StrUtil.isEmpty(sort.getParentCode()) : parentCode.equals(sort.getParentCode()))
        ).collect(Collectors.toList());

        // 将找到的子任务添加到平铺列表中
        flatChildrenList.addAll(children);

        // 对每个找到的子级递归寻找其子任务，并添加到平铺列表中
        for (ProjectProblemSort child : children) {
            findAllChildren(allSort, child.getProblemCode(), flatChildrenList);
        }
    }

    /**
     * 删除
     * @param projectProblemSortClass
     * @param key
     */
    @Override
    @Transactional
    public void deleteALL(Class<ProjectProblemSort> projectProblemSortClass, String key) {
        ProjectProblemSort byId = this.getById(projectProblemSortClass, key);
        if (byId.getParentCode()==null){//为真是根问题分类
            String proType = byId.getProType();
            JpaUtil.lind(ProjectProblemSort.class).equal("proType",proType).delete();//删除父级和子级
        }else {
            this.delete(projectProblemSortClass,key);//只删除当前问题分类
        }

    }

    @Override
    @Transactional
    public Result<?> add(ProjectProblemSort problemSort) {
        if (problemSort.getParentCode()!=null){
            this.save(problemSort);//添加子级
            return Result.OK(problemSort);
        }
        String proType = problemSort.getProType();
        List<ProjectProblemSort> list = this.list(ProjectProblemSort.class, Criteria.create());
        //判断问题类型是否已存在
        for (ProjectProblemSort projectProblemSort : list){
            if (projectProblemSort.getProType().equals(proType)){
                return Result.error("问题类型已存在");
            }
        }

        this.save(problemSort);
        return Result.OK(problemSort);
    }


}
